﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using ThiefRun.States;

namespace ThiefRun.Character
{
    public class Player : Character
    {
        #region Constants
        // Constants
        #endregion Constants

        #region Properties
        // Properties
        public enum Direction { Up, Down, Left, Right };
        public enum SpecialAction { Punch };
        #endregion Properties

        #region Computed Properties
        // Computed Properties
        #endregion Computed Properties


        //A Timer variable
        float timer = 0f;
        float punchTimer = 0f;
        //A Idle Timer variable
        float idleTimer = 0f;
        //The interval (100 milliseconds)
        float interval = 80f;

        //The idle interval WHEN PLAYER STOPS MOVING TO RESET SPRITE
        float idleInterval = 30f;
        //Current frame holder (start at 1)
        int currentFrame = 1;

        //Current row holder
        int currentRow = 0;
        //Width of a single sprite image, not the whole Sprite Sheet
        int spriteWidth = 105;
        //Height of a single sprite image, not the whole Sprite Sheet
        int spriteHeight = 115;
        //A rectangle to store which 'frame' is currently being shown
        Rectangle sourceRect;

        float angle = 0f;
        bool animateSprite = false;
        bool punchSprite = false;

        Vector2 origin;

        #region Methods
        // Methods
        public Player(ThiefRunGame game, LevelState state, Texture2D texture, Vector2 position, Vector2 size, Vector2 direction, Vector2 velocity, Color colour,
            int level) : base(game, state, texture, position, size, direction, velocity, colour, level)
        {
            this.size = size / 2;
        }

        /// <summary>
        /// Move the character based on the input.
        /// </summary>
        /// <param name="direction">The direction to travel.</param>
        public void Move(Direction direction)
        {
            if (!punchSprite)
            {
                switch (direction)
                {
                    case Direction.Left:
                        linear.position.X -= linear.velocity.X;
                        currentRow = 0;
                        angle = (float)Math.PI;         // Rotate 180 degree
                        animateSprite = true;
                        break;
                    case Direction.Right:
                        linear.position.X += linear.velocity.X;
                        currentRow = 0;
                        angle = 0f;                     // Use original sprite
                        animateSprite = true;
                        break;
                    case Direction.Up:
                        linear.position.Y -= linear.velocity.Y;
                        currentRow = 0;
                        angle = (float)Math.PI + ((float)Math.PI / 2.0f);   // Rotate 90 degree up
                        animateSprite = true;
                        break;
                    case Direction.Down:
                        linear.position.Y += linear.velocity.Y;
                        currentRow = 0;
                        angle = (float)Math.PI / 2.0f;  // Rotate 90 degree down
                        animateSprite = true;
                        break;
                }
            }
            CheckBounds();
        }

        public void Action(SpecialAction action)
        {
            switch (action)
            {
                case SpecialAction.Punch:
                    punchSprite = true;
                    break;
            }
        }
        #endregion Methods

        public void Update(GameTime gameTime)
        {
            timer += (float)gameTime.ElapsedGameTime.TotalMilliseconds;
            punchTimer += (float)gameTime.ElapsedGameTime.TotalMilliseconds;

            idleTimer += (float)gameTime.ElapsedGameTime.TotalMilliseconds;
          
            if (animateSprite)
            {
                if (currentRow == 1)
                {
                    currentFrame = 0;
                    currentRow = 0;
                }
                idleTimer = (float)gameTime.ElapsedGameTime.TotalMilliseconds;
                if (timer > interval)
                {
                    //Show the next frame
                    currentFrame++;
                    //Reset the timer
                    timer = 0f;
                }
                //If we are on the last frame, reset back to the one before the first frame (because currentframe++ is called next so the next frame will be 1!)
                if (currentFrame == 7)
                {
                    currentFrame = 0;
                }
                sourceRect = new Rectangle(currentFrame * spriteWidth, currentRow * spriteHeight, spriteWidth, spriteHeight);
                origin = new Vector2(sourceRect.Width / 2, sourceRect.Height / 2);
                animateSprite = false;
            }


            if (punchSprite)
            {
                currentRow = 1;
                idleTimer = (float)gameTime.ElapsedGameTime.TotalMilliseconds;

                currentFrame = 3;

                if (timer > 200)
                {
                    currentFrame = 0;
                }

                if (timer > 400)
                    punchSprite = false;

                if (currentFrame == 4)
                {
                    currentFrame = 0;
                }

                if (currentFrame == 0)
                    sourceRect = new Rectangle(0, currentRow * spriteHeight, 135, spriteHeight);
                else
                    if (currentFrame == 1)
                        sourceRect = new Rectangle(135, currentRow * spriteHeight, 105, spriteHeight);
                    else
                        if (currentFrame == 2)
                            sourceRect = new Rectangle(240, currentRow * spriteHeight, 125, spriteHeight);
                        else
                            if (currentFrame == 3)
                                sourceRect = new Rectangle(365, currentRow * spriteHeight, 195, spriteHeight);

                origin = new Vector2(sourceRect.Width / 2, sourceRect.Height / 2);
            }

            if (idleTimer > idleInterval)
            {
                if (timer > interval)
                {
                    currentFrame = 0;
                    //Reset the timer
                    timer = 0f;

                    if(currentRow == 0)
                        sourceRect = new Rectangle(currentFrame * spriteWidth, currentRow * spriteHeight, spriteWidth, spriteHeight);
                    else
                        if(currentRow == 1)
                            sourceRect = new Rectangle(0, currentRow * spriteHeight, 135, spriteHeight);

                    origin = new Vector2(sourceRect.Width / 2, sourceRect.Height / 2);
                    
                }
            }           
        }

        
        public override void Draw(GameTime gameTime, SpriteBatch spriteBatch)
        {
            spriteBatch.Begin();
            spriteBatch.Draw(texture, linear.position, sourceRect, Color.White, angle, origin, 0.5f, SpriteEffects.None, 0);
            spriteBatch.End();
        }
    }
}
